﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using COFE.Core;

namespace COFE.Data.UnitTest
{
    [TestFixture]
    public class TestDBEntryPropertyManager
    {
        #region Constructor

        public static string TestVolumeKey = @"Temp";
        public static string TestVolumePath = @"C:\temp";

        static TestDBEntryPropertyManager()
        {
            COFEDBShared.Register(null, true);
            if (DBUserProfile.Exists("TestDBEntryPropertyManager"))
                DBUserProfile.Remove("TestDBEntryPropertyManager");
            IUserProfile user = DBUserProfile.Create("TestDBEntryPropertyManager", "TestDBEntryPropertyManager");
            if (COFEShared.VolumeRegistrar.LookupRegisterVolume(TestVolumeKey) == null)
                COFEShared.VolumeRegistrar.RegisterVolume(
                    COFEShared.VolumeRegistrar.ConstructVolume("FSI", TestVolumeKey, TestVolumePath, 
                    Core.Profile.VolumeAccessMode.All));

            user.RegisterVolume(TestVolumeKey);

            DummyDBPropertyProvider.EnableDummySecondaryPropertyProvider();
        }

        #endregion


        void RemoveCache()
        {
            COFEDBShared.DBOperations.UpdateDatabase((context) =>
                {
                    var dbEntry = COFEDBShared.DBEntryManager.LookupEntry(context, COFEShared.AdminUserProfile, parsableVolumeKey);
                    if (dbEntry != null)
                    {
                        var entryId = dbEntry.EntryId;
                        if (dbEntry != null)
                            COFEDBShared.DBEntryManager.RemoveEntry(entryId);
                        Assert.IsNull(COFEDBShared.DBEntryManager.LookupEntry(context, COFEShared.AdminUserProfile, entryId));
                    }
                });
        }

        void UpdateEntry(IInternalFileSystemInfoExA entry)
        {            
            Assert.IsNotNull(entry);
            COFEDBShared.DBEntryManager.UpdateEntry(entry.PrimaryPropertyProvider);
        }

        void ChangeProperty(IInternalFileSystemInfoExA entry)
        {
            Assert.IsNotNull(entry);
            DateTime changedDateTime = new DateTime(1979,08,14);
            entry.SetProperty(DatabaseProperties.LastListTime, changedDateTime);
            Assert.AreEqual(changedDateTime, entry.GetProperty(DatabaseProperties.LastListTime).ValueAsUtcDateTime);

            string dateString = changedDateTime.ToLongDateString();
            entry.SetProperty(COFE.Data.UnitTest.DummyDBPropertyProvider.DummyProperties.DummyString, dateString);
            Assert.AreEqual(dateString, entry.GetProperty(COFE.Data.UnitTest.DummyDBPropertyProvider.DummyProperties.DummyString).ValueAsString);
        }

        void CacheProperties(IInternalFileSystemInfoExA entry)
        {
            COFEDBShared.DBOperations.ReadDatabase(
                (context) => COFEDBShared.DBEntryManager.LookupEntry(context, entry.ParseName),
                (context, dbEntry) =>
                {
                    Assert.IsNotNull(dbEntry);
                    COFEDBShared.DBEntryPropertyManager.CacheProperties(dbEntry.EntryId, entry);
                });
            
            
        }

        void Benchmark(string name, Action action)
        {
            DateTime startTime = DateTime.UtcNow;
            action.Invoke();
            DateTime endTime = DateTime.UtcNow;
            Console.WriteLine(name + " - " + endTime.Subtract(startTime).TotalSeconds.ToString() + "s");
        }

        private string parsableVolumeKey { get { return "{" + TestVolumeKey + "}"; } }

        [Test]
        public void Test()
        {
            DBUserProfile.Login("TestDBEntryPropertyManager", "TestDBEntryPropertyManager");
            Assert.AreEqual("TestDBEntryPropertyManager", COFEShared.CurrentUserProfile.UserName);
            Assert.AreEqual(1, COFEShared.CurrentUserProfile.Volumes.PrimaryVolumes.Count);
            var root = COFEShared.CurrentUserProfile.TryParsePath(parsableVolumeKey) as IInternalDirectoryInfoExA;
            Assert.IsNotNull(root);


            Benchmark("RemoveCache", () => { RemoveCache(); });
            Benchmark("UpdateEntry", () => { UpdateEntry(root); });
            Benchmark("ChangeProperty", () => { ChangeProperty(root); });
            Benchmark("CacheProperties", () => { CacheProperties(root); });
            //Benchmark("AddParentToDatabase", () => { AddParentToDatabase(); });
            //Benchmark("WriteChildToDatabase", () => { WriteChildToDatabase(); });

            //Benchmark("ListChildFromDatabase", () => { ListChildFromDatabase(); });
            //Benchmark("ListChildFromDatabaseUsingDBDirectoryLister", () => { ListChildFromDatabaseUsingDBDirectoryLister(); });

        }

    }
}
